import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:frametrim/activity/loginPage.dart';
import 'package:frametrim/app/app_navigator.dart';
import 'package:frametrim/http/ApiUtils.dart';
import 'package:frametrim/utility/Tools.dart';
import 'package:frametrim/utility/dataServer.dart';
import 'package:frametrim/utility/log_utils.dart';
import 'package:frametrim/utility/sp_utils.dart';
import 'package:frametrim/utility/toast.dart';
import 'package:common_utils/common_utils.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

class HttpManager {
  static HttpManager? _instance;
  Response? response;
  String METHOD_POST = "POST";
  String METHOD_POSTJSON = "POST_JSON";
  String METHOD_GET = "GET";
  bool mShowDialog = true;
  var objMap = Map<String, Object>();

  static HttpManager getInstance() {
    _instance ??= HttpManager();
    return _instance!;
  }

  var dio = Dio();

  HttpManager() {
    dio.options.baseUrl = ApiUtils.BASE_URL;
    dio.options.connectTimeout = 5000;
    dio.options.receiveTimeout = 3000;
    dio.interceptors.add(LogInterceptor(responseBody: true)); //是否开启请求日志
  }

  HttpManager addHeader() {
    dio.options.headers["Authorization"] =
    "Bearer ${SPUtil.getString(DataServer.mUserToken)}";
    dio.options.headers["platform"] = SPUtil.getString(DataServer.mPlatform);
    dio.options.headers["phone"] = SPUtil.getString(DataServer.mPhone);
    // dio.options.headers["content-type"] ="multipart/form-data";
    return this;
  }

  HttpManager showDialog(bool isshow) {
    mShowDialog = isshow;
    return this;
  }

  //get方式请求
  get(BuildContext context,
      String url, {
        Map<String, dynamic>? params,
        String? contentType,
        Function? successCallBack,
        Function? errorCallBack,
        Function? afterCallBack,
      }) async {
    _requstHttp(context, url,
        method: METHOD_GET,
        contentType: contentType,
        params: params,
        successCallBack: successCallBack,
        errorCallBack: errorCallBack,
        afterCallBack: afterCallBack);
  }

  //post请求
  post(BuildContext context, String url,
      {Map<String, dynamic>? params,
        String? contentType,
        Function? successCallBack,
        Function? errorCallBack,
        Function? afterCallBack}) async {
    _requstHttp(context, url,
        method: METHOD_POST,
        contentType: contentType,
        params: params,
        successCallBack: successCallBack,
        errorCallBack: errorCallBack,
        afterCallBack: afterCallBack);
  }

  //post请求
  postJson(BuildContext context, String url,
      {Map<String, dynamic>? params,
        String? contentType,
        Function? successCallBack,
        Function? errorCallBack,
        Function? afterCallBack}) async {
    objMap['params'] = params!;
    _requstHttp(context, url,
        method: METHOD_POSTJSON,
        contentType: contentType,
        params: objMap,
        successCallBack: successCallBack,
        errorCallBack: errorCallBack,
        afterCallBack: afterCallBack);
  }

  _requstHttp(BuildContext context, String url,
      {Map<String, dynamic>? params,
        String? method,
        String? contentType,
        Function? successCallBack,
        Function? errorCallBack,
        Function? afterCallBack}) async {
    try {
      if (mShowDialog == true) {
        showLoading();
      }
      if (method == METHOD_POST) {
        if (params == null) {
          response = await dio.post(url,
              options:
              Options(contentType: contentType ?? Headers.jsonContentType));
        } else {
          response = await dio.post(url,
              data: params,
              options:
              Options(contentType: contentType ?? Headers.jsonContentType));
        }
      } else if (method == METHOD_GET) {
        if (params == null) {
          response = await dio.get(url,
              options:
              Options(contentType: contentType ?? Headers.jsonContentType));
        } else {
          response = await dio.get(url,
              queryParameters: params,
              options:
              Options(contentType: contentType ?? Headers.jsonContentType));
        }
      } else if (method == METHOD_POSTJSON) {
        if (params != null) {
          response = await dio.post(url,
              data: Tools.mapToJson(params!),
              options:
              Options(contentType: contentType ?? Headers.jsonContentType));
        }
      }
    } on DioError catch (error) {
      if (afterCallBack != null) {
        afterCallBack!();
      }

      dismissLoading();
      //请求错误处理
      Response? errorResponse;
      if (error.response != null) {
        errorResponse = error.response;
      } else {
        errorResponse = Response(
            statusCode: 201, requestOptions: RequestOptions(path: 'null'));
      }
      response = errorResponse;
      // debug模式才打印
      if (ApiUtils.ISDEBUG) {
        LogUtils.e('请求异常: $error');
      }
      ToastUtils.show(error.message);
      _error(errorCallBack, error.message);

      return;
      // return '';
    }
    dismissLoading();
    if (afterCallBack != null) {
      afterCallBack!();
    }
    //打印
    _log(url, params);
    //解析结果
    String dataStr = json.encode(response!.data);
    Map<String, dynamic> dataMap = json.decode(dataStr);
    var code = dataMap['code'];
    if (code == 900) {
      successCallBack!(dataMap);
    } else {
      _error(errorCallBack, dataMap['message']);
      if (code == 901) {
        //未登录
        SPUtil.clear();
        AppNavigator.pushAndRemove(context, LoginPage());
      }
    }

  }

  _error(Function? errorCallBack, String error) {
    ToastUtils.show(error);
    if (errorCallBack != null) {
      errorCallBack(error);
    }
  }

//打印
  _log(String url, Map<String, dynamic>? params) {
    if (ApiUtils.ISDEBUG) {
      LogUtil.d('请求url$url');
      LogUtil.d('请求头: ${dio.options.headers}');
      if (params != null) {
        LogUtil.d('请求参数: $params');
      }
      if (response != null) {
        //LogUtil.d  能打印完整
        LogUtil.d('返回参数: $response');
      }
    }
  }

  void showLoading() {
    if (!EasyLoading.isShow) {
      EasyLoading.show(status: '加载中...');
    }
  }

  void dismissLoading() {
    if (EasyLoading.isShow) {
      EasyLoading.dismiss();
    }
  }
}
